/* eslint-disable no-param-reassign */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable camelcase */
/* eslint-disable array-callback-return */
import { computed, defineComponent, Ref, ref, watch } from 'vue';
import {
  getEditorEmits,
  getInputProps,
  useNamespace,
} from '@ibiz-template/vue3-util';
import { clone } from '@ibiz-template/core';
import { GroupShiftsController } from './group-shifts.controller';
import './group-shifts.scss';

export const GroupShifts = defineComponent({
  name: 'IBizGroupShifts',
  props: {
    ...getInputProps<GroupShiftsController>(),
    value: {
      type: Array<IData>,
      default: () => [],
    },
  },
  emits: getEditorEmits(),
  setup(props, { emit }) {
    const c = props.controller;
    const ns = useNamespace('group-shifts');

    // 是否展开表格进行编辑
    const isEditor = ref(false);
    // 所有workdays数据
    const allWorkdays: Ref<IData[][]> = ref([]);

    // 排班数据
    const shifts: Ref<IData[]> = ref([]);
    // 当前表单workdays临时数据
    const tempValue: Ref<IData[]> = ref([]);
    // 大表单数据
    const bigData: Ref<IData | undefined | null> = ref();
    // 当前选择值转换文本
    const curValue = ref('');
    // 上A休B 工作配置
    // 工作多少天
    const workNum = ref(0);
    // 休息多少天
    const restNum = ref(0);
    // N班倒-休息日相同
    const isEqualRestday = computed(() => {
      return (
        bigData.value &&
        bigData.value.schedule_type === 'class_inversion' &&
        bigData.value.same_restday === 1
      );
    });
    // N班倒-休息日不同
    const isNotEqualRestday = computed(() => {
      return (
        bigData.value &&
        bigData.value.schedule_type === 'class_inversion' &&
        bigData.value.same_restday === 0
      );
    });
    // 上A休B
    const isWorkRest = computed(() => {
      return bigData.value && bigData.value.schedule_type === 'work_rest';
    });

    watch(
      () => props.value,
      async newVal => {
        tempValue.value = clone(newVal) || [];
        shifts.value = await c.loadShifts();
        bigData.value = c.getBigFormData();
        if (bigData.value) {
          workNum.value = bigData.value.work || 0;
          restNum.value = bigData.value.rest || 0;
          if (bigData.value.schedule_type === 'class_inversion') {
            curValue.value = props.value
              ?.map(item => {
                const { shift_id } = item;
                const index = shifts.value.findIndex(
                  shift => shift.id === shift_id,
                );
                if (index > -1) {
                  return shifts.value[index].name;
                }
                if (item.is_work === 0) {
                  const _index = props.value?.findIndex(
                    _item => !!_item.shift_id,
                  );
                  if (_index > -1) {
                    return '休息';
                  }
                }
              })
              .filter(item => !!item)
              .join('/');
          }
          if (bigData.value.schedule_type === 'work_rest') {
            const tag = props.value?.some(item => {
              return item.is_work === undefined;
            });
            if (!tag) {
              curValue.value = props.value
                ?.map(item => {
                  if (item.is_work === 0) {
                    return '休息';
                  }
                  return '工作';
                })
                .join('/');
            }
          }
        }
      },
      {
        immediate: true,
        deep: true,
      },
    );

    // 点击展开表格
    const onClick = async () => {
      shifts.value = await c.loadShifts();
      const workDays = await c.loadAllWorkDays();
      bigData.value = c.getBigFormData();
      // 获取所有表单的排班数据并整合，用于绘制左上角的点
      if (workDays) {
        allWorkdays.value = workDays.map((item: IData) => item.workdays || []);
      }
      isEditor.value = !isEditor.value;
    };

    // 保存
    const onSave = async () => {
      let flag = false;
      // N班倒-休息日相同
      if (isEqualRestday.value) {
        flag = tempValue.value.some(item => !!item.is_work && !item.shift_id);
      }
      // N班倒-休息日不同
      if (isNotEqualRestday.value) {
        flag = tempValue.value.some(item => {
          return !item.shift_id && item.is_work !== 0;
        });
      }
      // 上A休B
      if (isWorkRest.value) {
        const restdays = tempValue.value.filter(item => {
          return item.is_work === 0;
        });
        flag = restdays.length !== restNum.value;
      }
      if (flag) {
        ibiz.modal.warning({
          title: '警告',
          desc: '请填充完整表单',
        });
      } else {
        emit('change', tempValue.value);
        isEditor.value = false;
      }
    };

    // 点击单元格
    const onSelect = (
      index: number,
      id: string,
      deleteIsWork: boolean = false,
    ) => {
      const item = tempValue.value[index];
      item.shift_id = id;
      if (deleteIsWork) {
        delete item.is_work;
      }
      tempValue.value.splice(index, 1, item);
    };

    // 点击休息日
    const onRestdayClick = (index: number) => {
      const item = tempValue.value[index];
      item.is_work = 0;
      delete item.shift_id;
      tempValue.value.splice(index, 1, item);
    };

    // 上A休B 点击
    const onClickWorkRest = (index: number) => {
      const item = tempValue.value[index];
      if (item.is_work === 1) {
        return;
      }
      if (item.is_work === 0) {
        item.is_work = undefined;
      } else if (!item.is_work) {
        item.is_work = 0;
      }
      tempValue.value.splice(index, 1, item);

      const restdays = tempValue.value.filter(
        (_item: IData) => _item.is_work === 0,
      );
      if (restdays.length === restNum.value) {
        tempValue.value.map((_item: IData) => {
          if (_item.is_work === undefined) {
            _item.is_work = 1;
          }
        });
      }
      if (restdays.length < restNum.value) {
        tempValue.value.map((_item: IData) => {
          if (_item.is_work === 1) {
            _item.is_work = undefined;
          }
        });
      }
    };

    // 绘制star
    const renderStar = (
      index: number,
      id: string,
      isRestday: boolean = false,
    ) => {
      let starts = 0;
      allWorkdays.value.forEach((workdays: IData[]) => {
        if (workdays && workdays.length > 0) {
          const workday = workdays[index];

          if (isRestday) {
            if (workday.is_work === 0) {
              starts += 1;
            }
          } else if (workday.shift_id === id) {
            starts += 1;
          }
        }
      });
      if (starts > 0) {
        const tempItems = new Array(starts).fill(null).slice(0, 3);
        return (
          <div class={ns.e('start')}>
            {tempItems.map((_item: null, _index: number) => {
              return (
                <div
                  class={[ns.em('start', 'item'), ns.em('start', `${_index}`)]}
                ></div>
              );
            })}
          </div>
        );
      }
      return null;
    };

    // 绘制排班,N班倒-休息日相同
    const renderShifts = (item: IData, index: number) => {
      // 休息日
      if (!item.is_work) {
        return (
          <div
            class={[ns.em('item', 'shift-item'), ns.is('restday', true)]}
            style={{ height: `${shifts.value.length * 54}px` }}
          >
            休息日
          </div>
        );
      }
      // 非休息日
      return shifts.value.map((_item: IData) => {
        return (
          <div
            class={[
              ns.em('item', 'shift-item'),
              ns.is('selected', _item.id === item.shift_id),
            ]}
            onClick={() => onSelect(index, _item.id)}
          >
            {renderStar(index, _item.id)}
            {_item.name}
          </div>
        );
      });
    };

    // 绘制 N班倒-不同休息日
    const renderDifferentRestdays = (item: IData, index: number) => {
      return (
        <div class={ns.e('differen-restdays')}>
          {shifts.value.map((_item: IData) => {
            return (
              <div
                class={[
                  ns.em('differen-restdays', 'shift-item'),
                  ns.is('selected', _item.id === item.shift_id),
                ]}
                onClick={() => onSelect(index, _item.id, true)}
              >
                {renderStar(index, _item.id)}
                {_item.name}
              </div>
            );
          })}
          <div
            class={[
              ns.em('differen-restdays', 'shift-item'),
              ns.is('selected', item.is_work === 0),
            ]}
            onClick={() => onRestdayClick(index)}
          >
            {renderStar(index, item.id, true)}
            休息
          </div>
        </div>
      );
    };

    // 绘制上A休B
    const renderWorkARestB = (item: IData, index: number) => {
      return (
        <div
          class={[
            ns.e('work-rest'),
            ns.is('selected', item.is_work === 0),
            ns.is('work', item.is_work === 1),
          ]}
          onClick={() => onClickWorkRest(index)}
        >
          {renderStar(index, '', true)}
          {item.is_work === 1 ? '工作' : '休息'}
        </div>
      );
    };
    // 绘制不同模式的排班
    const renderShiftByMode = (item: IData, index: number) => {
      if (bigData.value) {
        if (bigData.value.schedule_type === 'class_inversion') {
          if (bigData.value.same_restday === 1) {
            // N班倒-相同休息日
            return renderShifts(item, index);
          }
          if (bigData.value.same_restday === 0) {
            // N班倒-不同休息日
            return renderDifferentRestdays(item, index);
          }
        }
        if (bigData.value.schedule_type === 'work_rest') {
          // 上A休B
          return renderWorkARestB(item, index);
        }
      }
    };

    // 绘制周列表
    const renderWeekList = () => {
      if (isEditor.value) {
        return (
          <div class={ns.e('weeklist')}>
            <div class={ns.e('save')}>
              <div class={ns.em('save', 'btn')} onClick={onSave}>
                保存
              </div>
            </div>
            <div class={ns.e('week')}>
              {tempValue.value.map((item: IData, index: number) => {
                return (
                  <div class={ns.e('item')}>
                    <div class={ns.em('item', 'week-title')}>{item.name}</div>
                    {renderShiftByMode(item, index)}
                  </div>
                );
              })}
            </div>
          </div>
        );
      }
    };

    return {
      ns,
      isEditor,
      curValue,
      tempValue,
      shifts,
      bigData,
      onSelect,
      onSave,
      onClick,
      renderStar,
      renderShifts,
      renderWeekList,
    };
  },
  render() {
    const editorStyle: IData = {
      width: '100%',
    };
    if (this.isEditor && this.shifts.length > 0) {
      let height = this.shifts.length + 1;
      if (
        this.bigData &&
        this.bigData.schedule_type === 'class_inversion' &&
        this.bigData.same_restday === 0
      ) {
        height += 1;
      }
      editorStyle.height = `${54 * height + 94}px`;
    }
    return (
      <div class={this.ns.b()} style={editorStyle}>
        <div onClick={this.onClick}>
          <el-input value={this.curValue} readonly></el-input>
        </div>
        {this.renderWeekList()}
      </div>
    );
  },
});
